package com.reger.l2cache.pipeline.ops;

import java.util.List;

import org.springframework.data.redis.connection.ReturnType;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.DigestUtils;

import io.lettuce.core.RedisCommandExecutionException;

public interface RedisScriptingPipeline {
	void scriptFlush();

	void scriptKill();

	@Nullable
	String scriptLoad(String script);

	@Nullable
	List<Boolean> scriptExists(String... scriptShas);

	@Nullable
	<T> T eval(String script, ReturnType returnType, int numKeys, byte[]... keysAndArgs);

	@Nullable
	<T> T evalSha(String scriptSha, ReturnType returnType, int numKeys, byte[]... keysAndArgs);

	@Nullable
	default <T> T evalShaElsf(String script, ReturnType returnType, int numKeys, byte[]... keysAndArgs) {
		try {
			Assert.hasText(script, "脚本不可以为空");
			String scriptSha = DigestUtils.md5DigestAsHex(script.getBytes());
			return evalSha(scriptSha, returnType, numKeys, keysAndArgs);
		} catch (Exception e) {
			if (e.getCause() instanceof RedisCommandExecutionException) {
				return eval(script, returnType, numKeys, keysAndArgs);
			} else {
				throw e;
			}
		}
	}

	default RedisScriptingPipeline toSPPl() {
		return this;
	}
}
